package com.step.ems.component

import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.LocalOverscrollConfiguration
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.step.ems.R
import com.step.ems.common.RefreshType
import com.step.ems.common.UiState

@OptIn(ExperimentalFoundationApi::class)
@Composable
internal fun <T> EndlessLazyColumn(
    modifier: Modifier = Modifier,
    uiState: UiState,
    listState: LazyListState = rememberLazyListState(),
    items: List<T>,
    itemKey: (T) -> Any,
    loadMore: () -> Unit,
    itemContent: @Composable (T) -> Unit,
) {

    val reachedBottom: Boolean by remember { derivedStateOf { listState.reachedBottom() } }

    LaunchedEffect(reachedBottom) {
        if (reachedBottom && uiState !is UiState.Loading) loadMore()
    }
    CompositionLocalProvider(LocalOverscrollConfiguration provides null) {
        LazyColumn(modifier = modifier, state = listState) {
            items(
                items = items,
                key = { item: T -> itemKey(item) },
            ) { item ->
                itemContent(item)
            }
            item {
                when (uiState) {
                    is UiState.Loading -> {
                        if (uiState.type == RefreshType.Init || uiState.type == RefreshType.LoadMore) {
                            LoadMore(stringResource(R.string.loading))
                        }
                    }

                    is UiState.Success -> {
                        LoadMore(stringResource(R.string.loadingCompleted))
                    }

                    is UiState.Error -> {
                        LoadMore(stringResource(R.string.loadingError))
                    }

                    else -> Unit
                }
            }
        }
    }
}

@Composable
private fun LoadMore(text: String) {
    Text(
        text = text,
        modifier = Modifier
            .fillMaxWidth()
            .padding(top = 6.dp, bottom = 10.dp), textAlign = TextAlign.Center,
        fontSize = 15.sp,
        color = Color(0xFF666666)
    )
}


private fun LazyListState.reachedBottom(): Boolean {
    val lastVisibleItem = this.layoutInfo.visibleItemsInfo.lastOrNull()
    return lastVisibleItem?.index != 0 && lastVisibleItem?.index == this.layoutInfo.totalItemsCount - 1
}